﻿using K9Nano.Updater.Exceptions;
using K9Nano.Updater.Server.Authorization;

namespace K9Nano.Updater.Server.Internals;

internal class ReleaseManager(IReleaseStore releaseStore, IClientContextAccessor clientContextAccessor, IClientStore clientStore) : IReleaseManager
{
    public ValueTask<AvailableVersion?> GetLatestVersionAsync(CancellationToken cancellation = default)
    {
        return releaseStore.GetLatestVersionAsync(clientContextAccessor.RequiredClientId, cancellation);
    }

    public ValueTask<ReleaseMetadata?> GetMetadataAsync(Version version, CancellationToken cancellation = default)
    {
        return releaseStore.GetMetadataAsync(clientContextAccessor.RequiredClientId, version, cancellation);
    }

    public ValueTask<ReleaseFile?> GetReleaseFileAsync(Version version, string fileUri, CancellationToken cancellation = default)
    {
        return releaseStore.GetReleaseFileAsync(clientContextAccessor.RequiredClientId, version, fileUri, cancellation);
    }

    public async ValueTask<IEnumerable<ReleaseInfo>> GetAllReleasesAsync(string clientId, CancellationToken cancellation = default)
    {
        if (!await clientStore.EixtsAsync(clientId, cancellation))
        {
            return [];
        }

        return await releaseStore.GetAllReleasesAsync(clientId, cancellation);
    }

    public async ValueTask<string> GetReleaseLogFileAsync(string clientId, Version version, CancellationToken cancellation = default)
    {
        if (!await clientStore.EixtsAsync(clientId, cancellation))
        {
            return string.Empty;
        }

        return await releaseStore.GetReleaseLogFileAsync(clientId, version, cancellation);
    }

    public async ValueTask SaveAsync(string clientId, Version version, Stream zipStream, CancellationToken cancellation = default)
    {
        if (!await clientStore.EixtsAsync(clientId, cancellation))
        {
            throw new UpdateException("ClientId无效: " + clientId);
        }

        if (await releaseStore.ExistsAsync(clientId, version, cancellation))
        {
            throw new UpdateException("指定版本已经存在: " + version);
        }

        await releaseStore.SaveAsync(clientId, version, zipStream, cancellation);
    }

    public async ValueTask<bool> ExistsAsync(string clientId, Version version, CancellationToken cancellation = default)
    {
        if (!await clientStore.EixtsAsync(clientId, cancellation))
        {
            return false;
        }
        return await releaseStore.ExistsAsync(clientId, version, cancellation).ConfigureAwait(false);
    }
}
